struct Bank {
    balance: Vec<i64>,
    n: i32,
}

/**
 * `&self` means the method takes an immutable reference.
 * If you need a mutable reference, change it to `&mut self` instead.
 */

impl Bank {
    fn new(balance: Vec<i64>) -> Self {
        Bank {
            balance: balance.clone(),
            n: balance.len() as i32,
        }
    }

    fn check(&self, account: i32) -> bool {
        1 <= account && account <= self.n
    }

    fn transfer(&mut self, account1: i32, account2: i32, money: i64) -> bool {
        if !self.check(account1) || !self.check(account2) {
            return false;
        }
        if self.balance[account1 as usize - 1] < money {
            return false;
        }

        self.balance[account1 as usize - 1] -= money;
        self.balance[account2 as usize - 1] += money;

        true
    }

    fn deposit(&mut self, account: i32, money: i64) -> bool {
        if !self.check(account) {
            return false;
        }

        self.balance[account as usize - 1] += money;
        true
    }

    fn withdraw(&mut self, account: i32, money: i64) -> bool {
        if !self.check(account) {
            return false;
        }

        if self.balance[account as usize - 1] < money {
            return false;
        }
        self.balance[account as usize - 1] -= money;
        true
    }

}

/**
 * Your Bank object will be instantiated and called as such:
 * let obj = Bank::new(balance);
 * let ret_1: bool = obj.transfer(account1, account2, money);
 * let ret_2: bool = obj.deposit(account, money);
 * let ret_3: bool = obj.withdraw(account, money);
 */

// 测试集，nice!!
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test1() {
        let result = 2 + 2;
        assert_eq!(result, 4);
        let mut bank = Bank::new(vec![10, 100, 20, 50, 30]);
        assert_eq!(bank.withdraw(3, 10), true);
        assert_eq!(bank.transfer(5, 1, 20), true);
        assert_eq!(bank.deposit(5, 20), true);
        assert_eq!(bank.transfer(3, 4, 15), false);
        assert_eq!(bank.withdraw(10, 50), false);

        // ["Bank","withdraw","transfer","deposit","transfer","withdraw"]
        // [[[10,100,20,50,30]],[3,10],[5,1,20],[5,20],[3,4,15],[10,50]]
        // [null,true,true,true,false,false]
    }
}

fn main() {
    // 不加main函数，会提示要加
}

// 运行要放在main.rs文件里
// main.rs和Bank.rs在同一目录里，Bank.rs是没有运行按钮的(用的IDE为Clion)